using System;
using System.Collections.Generic;

namespace AbstractClass.Extensions
{
    /// <summary>
    /// Provides a set of extension methods for <see cref="Exception"/>.
    /// </summary>
    public static class ExceptionExtensions
    {

        /// <summary>
        /// Gets the details of all the inner exceptions of the <paramref name="exception"/>.
        /// </summary>
        /// <param name="exception">The exception to get the details of.</param>
        /// <returns>The detailed message and stack traces of all inner exceptions.</returns>
        public static string GetDetails(this Exception exception)
        {
            var listOfException = GetAllExceptions(exception);
            var msg = string.Empty;
            var stackTraces = string.Empty;
            var count = 0;

            foreach (var e in listOfException)
            {
                msg += e.GetType() + ": " + e.Message + " ---> ";
                if (count == 0)
                    stackTraces += e.StackTrace;
                else
                    stackTraces = e.StackTrace + Environment.NewLine + @"   --- End of inner exception stack trace ---" +
                                 Environment.NewLine + stackTraces;
                count++;
            }
            return msg + Environment.NewLine + stackTraces;
        }

        private static IEnumerable<Exception> GetAllExceptions(Exception exception)
        {
            var list = new List<Exception> {exception};
            if(exception.InnerException != null)
                list.AddRange(GetAllExceptions(exception.InnerException));

            return list;
        }
    }
}